/*
 *
 * 应用启动时调用 AbstractApplicationContext.refresh() 方法
 *
 * Bean对象的生命周期
 *  1.bean创建(这里是指通过构造器赋值后创建了bean对象)
 *  2.初始化(spring对bean生命周期中的一部分)
 *  3.销毁的过程(spring对bean生命周期的管理)
 *
 * BeanPostProcessor 后置处理器对所有单例bean都会生效
 *
 * 容器管理bean的生命周期；我们可以自定义初始化和销毁方法；容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
 * 执行流程：通过构造器创建Bean的实例化对象 --> 执行后置处理器的Before方法 --> 执行spring支持的初始化方法 --> 执行后置处理器的After方法 --> 执行spring支持的销毁方法
 *  构造（对象创建即调用了对象的构造器方法生成了一个具体的对象）:
 *      1.单实例：在容器启动的时候创建对象
 *      2.多实例：在每次获取的时候创建对象
 *
 *  执行BeanPostProcessor.postProcessBeforeInitialization
 *
 *  初始化：对象创建完成，并赋值好，调用初始化方法。
 *         初始化方法：@Autowired
 *                  1.通过@Bean指定init-method
 *                  2.通过让Bean对象实现InitializingBean
 *                  3.可以使用JSR250，@PostConstruct：在bean创建完成并且属性赋值完成；来执行初始化方法
 *
 *  执行BeanPostProcessor.postProcessAfterInitialization
 *
 *  销毁（销毁容器内的Bean对象）：
 *      1.单实例：容器关闭的时候
 *      2.多实例：容器不会管理这个bean；容器不会调用销毁方法；
 *      销毁方式：
 *          1.通过@Bean指定destroy-method；
 *          2.通过让Bean对象实现DisposableBean接口（定义销毁逻辑）
 *          3.可以使用JSR250 @PreDestroy：在容器销毁bean之前通知我们进行清理工作
 *
 *
 *  生命周期原理代码解读：
 *      1.SpringApplication.run(SpringBootPrincipleApplication.class, args);
 *      2.SpringApplication.ConfigurableApplicationContext() ---> refreshContext(context);
 *      3.AbstractApplicationContext.refresh()
 *      4.finishBeanFactoryInitialization()
 *      5.beanFactory.preInstantiateSingletons();
 *      6.getBean(beanName);
 *      7.doGetBean(beanName)
 *      8.createBean(beanName, mbd, args);
 *      9.AbstractAutowireCapableBeanFactory.createBean
 *      10.AbstractAutowireCapableBeanFactory.doCreateBean
 *          populateBean(beanName, mbd, instanceWrapper); // 为bean对象的属性值
 * 			exposedObject = initializeBean(beanName, exposedObject, mbd); // 进入spring的初始化bean对象方法
 *      11.AbstractAutowireCapableBeanFactory.initializeBean() // 生命周期具体实现的位置
 *
 *                  invokeAwareMethods(beanName, bean); // 执行 Aware 实现类
 *          		Object wrappedBean = bean;
 * 		            if (mbd == null || !mbd.isSynthetic()) {
 * 			            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); // 先执行所有Bean后置处理器的Before方法
 *                   }
 *
 * 		            try {
 * 			            invokeInitMethods(beanName, wrappedBean, mbd); // 在执行spring支持的初始化方法 如：注解，实现接口等
 *                   }
 * 		            catch (Throwable ex) {
 * 			            throw new BeanCreationException(
 * 					        (mbd != null ? mbd.getResourceDescription() : null),
 * 					        beanName, "Invocation of init method failed", ex);
 *                  }
 * 		            if (mbd == null || !mbd.isSynthetic()) {
 * 			            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); // 最后执行所有Bean后置处理器的After方法
 *                  }
 *
 *      值得注意的是：执行Bean后置处理的方法时，如果某一个实现类返回的结果是null。就直接返回当前创建的bean对象
 *      		    Object result = existingBean;
 * 		            for (BeanPostProcessor processor : getBeanPostProcessors()) {
 * 			            Object current = processor.postProcessBeforeInitialization(result, beanName);
 * 			            if (current == null) {
 * 				            return result; // 如果为null直接返回，意思就是后面的处理器也全部不执行了
 *                      }
 * 			            result = current;
 *                  }
 *
 * spring内部对 后置处理器 BeanPostProcessor 的使用
 *      1.在Bean对象内部，聚合一个其他组件。通过 After 方法注入属性值
 *      2.对注解功能原理的支持 如：@Autowired
 */
package com.wzw.springboot.principle.lifecycle.bean;